package com.gp.dal.plugins;

import java.util.List;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;

/**
 * 自定义实现mybatis插件：把sql和parameters打印出来 插件执行的方法有：query/update
 * 
 * @author 张贵东
 */
@Intercepts({
		@Signature(type = Executor.class, method = "query", args = {
				MappedStatement.class, Object.class, RowBounds.class,
				ResultHandler.class }),
		@Signature(type = Executor.class, method = "update", args = {
				MappedStatement.class, Object.class }) })
public class MyPlugin implements Interceptor {

	public Object intercept(Invocation invocation) throws Throwable {

		Object[] args = invocation.getArgs();// 代理对象方法参数

		MappedStatement mappedStatement = (MappedStatement) args[0];// 方法参数
		Object parameterObject = null;
		if (args.length > 1) {
			parameterObject = args[1];
		}
		// 获取statementId:是Mapper接口中被调用的方法名:com.gp.dal.mapper.UserMapper.selectByPrimaryKey
		String statementId = mappedStatement.getId();
		// 获取绑定的SQL
		BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
		// Configuration configuration = mappedStatement.getConfiguration();
		String sql = boundSql.getSql();
		List<ParameterMapping> parameterMappings = boundSql
				.getParameterMappings();
		parameterMappings.get(0);
		Configuration configuration = mappedStatement.getConfiguration();
		TypeHandlerRegistry typeHandlerRegistry = configuration
				.getTypeHandlerRegistry();
		Object result = invocation.proceed();
		System.out.println("statementId=" + statementId);
		System.out.println("这是我自己实现的SQL输出：");
		System.out.println("sql=" + sql);
		for (ParameterMapping parameterMapping : parameterMappings) {
			String propertyName = parameterMapping.getProperty();
			Object value;
			if (boundSql.hasAdditionalParameter(propertyName)) {
				value = boundSql.getAdditionalParameter(propertyName);
			} else if (parameterObject == null) {
				value = null;
			} else if (typeHandlerRegistry.hasTypeHandler(parameterObject
					.getClass())) {
				value = parameterObject;
			} else {
				MetaObject metaObject = configuration
						.newMetaObject(parameterObject);
				value = metaObject.getValue(propertyName);
			}
			System.out.println("propertyName=" + propertyName + ",value="
					+ value);
		}

		return result;
	}

	public Object plugin(Object target) {
		if (target instanceof Executor) {
			return Plugin.wrap(target, this);
		} else {
			return target;
		}
	}

	public void setProperties(Properties properties) {
		String dialect = properties.getProperty("dialect");
	}

}
